var sys = require("@native.builtin");
var ntcp = require("@native.tcp");
require("eventbus.js");

EVENT_RECV = "data";
EVENT_END = "end";
EVENT_ERROR = "error";
EVENT_CLOSE = "close";

function TcpClient(fd) {
    this.fd = fd;
    this.__id__ = -1;
    this.on = function (event, callback) {
        if(event != EVENT_RECV && event != EVENT_END && event != EVENT_ERROR && event != EVENT_CLOSE)
            return undefined;

        this.__id__ = globalThis.eventbus.on(this, event, callback);
        ntcp.on(this.fd, this.__id__, event);
    };

    this.send = function (opt) {
        var buffer = opt.data;
        if (buffer == undefined || buffer.length == 0) return undefined;
        var size = buffer.length;
        var data = sys.malloc(size);
        if (data == null) return undefined;
        sys.copy(data, buffer, size);
        ntcp.send(this.fd, data, size);
        sys.free(data);
    };

    this.close = function () {
        ntcp.close(this.fd);
        globalThis.eventbus.detach(this);
    };
}

function createClient (opts) {
    var ip = opts["ip"];
    var port = opts["port"];
    var success = opts["success"];
    var fail = opts["fail"];

    if (ip == undefined || ip.length == 0 || typeof ip != "string")
        return undefined;

    if (port == undefined || typeof port != "number") 
        return undefined;

        var size = ip.length;
        var host = sys.malloc(size);
        if (host == null) return undefined;
        sys.copy(host, ip, size);

        var fd = ntcp.connect(host, port);
        sys.free(host);

    if (fd < 0) {
        if (typeof fail == "function") {
            fail();
        }
        return undefined;
    }

    if (typeof success == "function") {
        success();
    }
    return new TcpClient(fd);
}
